package problem;

import java.util.Arrays;
import java.util.Set;

import core.ObjectiveTarget;
import core.Problem;
import core.Result;

public class ProblemZDT1 extends Problem {
	
	
	
	public ProblemZDT1() {
		this.name = "ZDT1";
		this.restLowerBounds = 0;
		this.restUpperBounds = 1;
		this.firstLowerBounds = new double[0];
		this.firstUpperBounds = new double[0];
		this.objectiveTargets = new ObjectiveTarget[2];
		this.objectiveTargets[0] = ObjectiveTarget.MINIMIZE;
		this.objectiveTargets[1] = ObjectiveTarget.MINIMIZE;

	}

	@Override
	public double[] calculate(double[] genotype) {
		double sum = 0.;
		try {
			int i=1;
			while(true) {
				sum+=genotype[i++];
			}
		}catch(Exception e) {}
		double g = 1+9*(sum/(genotype.length-1));
		double tmp = genotype[0]/g;
		double f2 = g*(1.0 - Math.sqrt((tmp>0)?tmp:0.0));
		double[] result = new double[2];
		result[0] = genotype[0];
		result[1] = f2;
		return result;
	}
	
	@Override
	public String getOptimalSolution() {
		return "1-sqrt(x)";
	}

	@Override
	public double getHVR(Set<Result> results) {
		Result[]tmp = (Result[]) results.toArray();
		Arrays.sort(tmp, this.comparator);
//		for(Object s:tmp) {
//			System.out.print( "("+(s)[0]+"; "+(s)[1]+")," );
//		}
//		System.out.println();
		double hvrUp = 0.0;
		double hvrDown = 0.0;
		double last_val = 0.0;
		int i = 0;
		try {
			while(true) {
				hvrDown += (tmp[i].result)[1]*((tmp[i].result)[0]-last_val);
				hvrUp += (1.0-Math.sqrt((tmp[i].result)[0]))*((tmp[i].result)[0]-last_val);
				last_val = (tmp[i].result)[0];
				i++;
			}
		} catch (Exception e) {}
		return hvrUp/hvrDown;
	}

}
